package exam.utils;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 文件工具类
 */
public class FileUtil {


    /**
     *  多文件上传工具类
     * @param fileList
     *              需要上传的文件数组
     * @param folderPath
     *              存放的服务器目标文件
     * @return
     *           给我一个key-value键值对，放着的以混淆后名字为key ，原文件名为value的键值对数组
     */
    public static Map<String,String> uploadFile(List<MultipartFile> fileList, String folderPath){

        Map<String,String> fileMap=new HashMap<>();

        //上传协议到服务器文件夹地址
        MultipartFile file = null;
        for (MultipartFile multipartFile : fileList) {
            file = multipartFile;
            if (!file.isEmpty()) {
                try {
                    //上传到服务器后，混淆过后的名字
                    String newFile = uploadFileSingle(file, folderPath);

                    //原文件名
                    String fileSrc = file.getOriginalFilename();

                    fileMap.put(newFile, fileSrc);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
        return fileMap;
    }

    /**
     * 单文件上传
     * @param file
     *          需要上传的文件
     * @param folderPath
     *          存在的服务器目标文件夹
     * @return
     *          上传文件名，是存放在服务器当中的已经被混淆过后的文件名
     */
    public static String uploadFileSingle(MultipartFile file,String folderPath){

        /*
          你是一个写上传文件方法的这个人
          1.我需要一个使用者给我的服务器存放文件的路径，我得先判断这个路径里面 到底存在么文件夹。防止
          使用者忘了在服务器里面创建文件夹了，他忘了 我帮他创建
          2.我为了存服务器中的文件，防止重名的出现，我要更改文件名，但是我在更改文件名的同时，我也要
          保留原先的文件名。我才变为混淆后的文件名
          3.拿到了更改之后的文件名，就将这个文件存放到指定目录下面。
          Java里面 输入与输出
         */
        //新上传文件名
        String newFile="";
        try {

            File filePath=new File(folderPath);
            if(!filePath.exists()){
                filePath.mkdirs();
            }

            //获取文件后缀名
            //String suffixName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));

            //UUID下的新文件名
            newFile=UUID.randomUUID().toString();

            byte[] bytes = file.getBytes();
            BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(
                    new File(folderPath+newFile)));
            stream.write(bytes);
            stream.close();



        } catch (Exception e) {
            e.printStackTrace();
        }

        return newFile;
    }

    /**
     * 下载文件
     * @param response
     * @param folderPath
     *              服务器文件地址
     * @param fileName
     *              混淆后的文件名
     * @param fileNameSrc
     *              原文件名
     */
    public static void downloadFile(HttpServletResponse response,String folderPath,String fileName,String fileNameSrc){

        File file = new File(folderPath, fileName);

        try {
            //解决文件名中文乱码问题
            fileNameSrc=java.net.URLEncoder.encode(fileNameSrc,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


        if (file.exists()) {
            response.setContentType("application/force-download;charset=UTF-8");// 设置强制下载不打开
            response.addHeader("Content-Disposition",
                    "attachment;fileName=" + fileNameSrc);// 设置源文件名

            response.setCharacterEncoding("UTF-8");
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                /**
                 * 从服务器的文件里面  读取进入输入流，并放到输入流的缓冲区里面
                 * 获取response输出流，将输入流一部分一部分的放到我们的输出流里面
                 * 完成response
                 */
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

}
